home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / tex / dvi / dvipssrc.zoo / dospecia.c < prev    next >
C/C++ Source or Header  |  1991-01-15  |  20KB  |  720 lines

  1. /*
  2.  *   This routine handles special commands;
  3.  *   predospecial() is for the prescan, dospecial() for the real thing.
  4.  */
  5. #include "structures.h" /* The copyright notice in that file is included too! */
  6.  
  7. #include <ctype.h>
  8. extern int atoi();
  9.  
  10. /*
  11.  *   These are the external routines called:
  12.  */
  13. /**/
  14. #ifdef TPIC
  15. /*
  16.  * Fri Mar  9 1990  jourdan@minos.inria.fr (MJ)
  17.  * Upgraded to accommodate tpic release 2.0 extended output language.
  18.  * Should prove upward compatible!
  19.  */
  20. extern void setPenSize();
  21. extern void flushPath();
  22. extern void flushDashed();
  23. extern void flushDashed();
  24. extern void addPath();
  25. extern void arc();
  26. extern void flushSpline();
  27. extern void shadeLast();
  28. extern void whitenLast();
  29. extern void blackenLast();
  30. extern void SetShade() ;
  31. #endif
  32. extern shalfword dvibyte() ;
  33. extern int add_header() ;
  34. extern void hvpos() ;
  35. extern void figcopyfile() ;
  36. extern char *malloc() ;
  37. extern void nlcmdout() ;
  38. extern void cmdout() ;
  39. extern void numout() ;
  40. extern void scout() ;
  41. extern void stringend() ;
  42. extern void error() ;
  43. extern void psflush() ;
  44. extern char errbuf[] ;
  45. extern shalfword linepos;
  46. extern Boolean usesspecial ;
  47. extern int landscape ;
  48. extern char *paperfmt ;
  49. extern char *nextstring;
  50. extern char *maxstring;
  51. extern char *oname;
  52. extern FILE *bitfile;
  53. extern int quiet;
  54. extern fontdesctype *curfnt ;
  55. extern int actualdpi ;
  56. extern int vactualdpi ;
  57. extern integer hh, vv;
  58. extern int lastfont ;
  59. extern real conv ;
  60. extern real vconv ;
  61.  
  62. #ifdef DEBUG
  63. extern integer debug_flag;
  64. #endif
  65. extern void scanfontcomments() ;
  66.  
  67. struct bangspecial {
  68.    struct bangspecial *next ;
  69.    char actualstuff[1] ; /* more space will actually be allocated */
  70. } *bangspecials = NULL ;
  71.  
  72. #ifdef EMTEX
  73. /* subset of emtex specials */
  74.  
  75. #define EMMAX 1613 /* maximum number of emtex special points */
  76. #define TRUE 1
  77. #define FALSE 0
  78.  
  79. struct empt {
  80.    shalfword point;
  81.    integer x, y;
  82. };
  83.  
  84. struct empt *empoints = NULL;
  85. boolean emused = FALSE;  /* true if em points used on this page */
  86. integer emx, emy;
  87.  
  88. struct emunit {
  89.    char *unit;
  90.    float factor;
  91. };
  92. struct emunit emtable[] = {
  93.   {"pt",72.27},
  94.   {"pc",72.27/12},
  95.   {"in",1.0},
  96.   {"bp",72.0},
  97.   {"cm",2.54},
  98.   {"mm",25.4},
  99.   {"dd",72.27/(1238/1157)},
  100.   {"cc",72.27/12/(1238/1157)},
  101.   {"sp",72.27*65536},
  102.   {"",0.0}
  103. };
  104.  
  105.  
  106. /* clear the empoints array if necessary */
  107. void
  108. emclear()
  109. {
  110. int i;
  111.    if (emused && empoints)
  112.       for (i=0; i<EMMAX; i++)
  113.          empoints[i].point = 0;
  114.    emused = FALSE ;
  115. }
  116.  
  117. /* put an empoint into the empoints array */
  118. struct empt *emptput(point, x, y)
  119. shalfword point;
  120. integer x, y;
  121. {
  122. int i, start;
  123.  
  124.    emused = TRUE;
  125.    start = point % EMMAX;
  126.    i = start;
  127.    while ( empoints[i].point != 0 ) {
  128.       if ( empoints[i].point == point )
  129.          break;
  130.       i++;
  131.       if (i >= EMMAX)
  132.          i = 0;
  133.       if (i == start) {
  134.      sprintf(errbuf,"!Too many em: special points");
  135.      error(errbuf);
  136.       }
  137.    }
  138.  
  139.    empoints[i].point = point;
  140.    empoints[i].x = x;
  141.    empoints[i].y = y;
  142.    return(&empoints[i]);
  143. }
  144.  
  145. /* get an empoint from the empoints array */
  146. struct empt *emptget(point)
  147. shalfword point;
  148. {
  149. int i, start;
  150.  
  151.    start = point % EMMAX;
  152.    i = start;
  153.    if (emused == TRUE)
  154.       while ( empoints[i].point != 0 ) {
  155.          if (empoints[i].point == point)
  156.             return(&empoints[i]);
  157.          i++;
  158.          if (i >= EMMAX)
  159.             i = 0;
  160.          if (i == start)
  161.             break;
  162.       }
  163.    sprintf(errbuf,"!em: point %d not defined",point);
  164.    error(errbuf);
  165.    return(NULL); /* never returns due to error */
  166. }
  167.  
  168.  
  169. /* convert width into dpi units */
  170. float emunits(width,unit)
  171. float width;
  172. char *unit;
  173. {
  174. struct emunit *p;
  175.     for (p=emtable; *(p->unit)!='\0'; p++) {
  176.        if (strcmp(p->unit,unit)==0)
  177.         return( width * actualdpi / p->factor );
  178.     }
  179.     return (-1.0); /* invalid unit */
  180. }
  181. #endif /* EMTEX */
  182.  
  183.  
  184. static void trytobreakout(p)
  185. register char *p ;
  186. {
  187.    register int i ;
  188.    register int instring = 0 ;
  189.    int lastc = 0 ;
  190.  
  191.    i = 0 ;
  192.    while (*p) {
  193.       if (i > 65 && *p == ' ' && instring == 0) {
  194.          (void)putc('\n', bitfile) ;
  195.          i = 0 ;
  196.       } else {
  197.          (void)putc(*p, bitfile) ;
  198.          i++ ;
  199.       }
  200.       if (*p == '(' && lastc != '\\')
  201.          instring = 1 ;
  202.       else if (*p == ')' && lastc != '\\')
  203.          instring = 0 ;
  204.       lastc = *p ;
  205.       p++ ;
  206.    }
  207. }
  208.  
  209. static void dobs(q)
  210. register struct bangspecial *q ;
  211. {
  212.    if (q) {
  213.       dobs(q->next) ;
  214.       trytobreakout(q->actualstuff) ;
  215.    }
  216. }
  217.  
  218. void
  219. outbangspecials() {
  220.    if (bangspecials) {
  221.       cmdout("TeXDict") ;
  222.       cmdout("begin") ;
  223.       cmdout("@defspecial\n") ;
  224.       dobs(bangspecials) ;
  225.       cmdout("\n@fedspecial") ;
  226.       cmdout("end") ;
  227.    }
  228. }
  229.  
  230. /* We recommend that new specials be handled by the following general
  231.  * (and extensible) scheme, in which the user specifies one or more
  232.  * `key=value' pairs separated by spaces.
  233.  * The known keys are given in KeyTab; they take values
  234.  * of one of the following types:
  235.  *
  236.  * None: no value, just a keyword (in which case the = sign is omitted)
  237.  * String: the value should be "<string without double-quotes"
  238.  *                          or '<string without single-quotes'
  239.  * Integer: the value should be a decimal integer (%d format)
  240.  * Number: the value should be a decimal integer or real (%f format)
  241.  * Dimension: like Number, but will be multiplied by the scaledsize
  242.  *       of the current font and converted to default PostScript units
  243.  * (Actually, strings are allowed in all cases; the delimiting quotes
  244.  *  are simply stripped off if present.)
  245.  *
  246.  */
  247.  
  248. typedef enum {None, String, Integer, Number, Dimension} ValTyp;
  249. typedef struct {
  250.    char    *Entry;
  251.    ValTyp  Type;
  252. } KeyDesc;
  253.  
  254. #define NKEYS    (sizeof(KeyTab)/sizeof(KeyTab[0]))
  255.  
  256. KeyDesc KeyTab[] = {{"psfile",  String}, /* j==0 in the routine below */
  257.                     {"ifffile", String}, /* j==1 */
  258.                     {"tekfile", String}, /* j==2 */
  259.                     {"hsize",   Number},
  260.                     {"vsize",   Number},
  261.                     {"hoffset", Number},
  262.                     {"voffset", Number},
  263.                     {"hscale",  Number},
  264.                     {"vscale",  Number},
  265.                     {"angle",   Number},
  266.                     {"llx", Number},
  267.                     {"lly", Number},
  268.                     {"urx", Number},
  269.                     {"ury", Number},
  270.                     {"rwi", Number}};
  271.  
  272. #ifdef VMS
  273. #define Tolower _tolower
  274. #else
  275. /*
  276.  * compare strings, ignore case
  277.  */
  278. char Tolower(c)
  279. register char c ;
  280. {
  281.    if ('A' <= c && c <= 'Z')
  282.       return(c+32) ;
  283.    else
  284.       return(c) ;
  285. }
  286. #endif
  287. int IsSame(a, b)
  288. char *a, *b;
  289. {
  290.    for( ; *a != '\0'; )
  291.       if( Tolower(*a++) != Tolower(*b++) ) 
  292.          return( 0 );
  293.       return( *b == '\0' );
  294. }
  295.  
  296. char *KeyStr, *ValStr ; /* Key and String values found */
  297. long ValInt ; /* Integer value found */
  298. float ValNum ; /* Number or Dimension value found */
  299.  
  300. char  *GetKeyVal(str,tno) /* returns NULL if none found, else next scan point */
  301.    char *str ; /* starting point for scan */
  302.    int  *tno ; /* table entry number of keyword, or -1 if keyword not found */
  303. {
  304.    register char *s ;
  305.    register int i ;
  306.    register char t ;
  307.  
  308.    for (s=str; *s <= ' ' && *s; s++) ; /* skip over blanks */
  309.    if (*s == '\0')
  310.       return (NULL) ;
  311.    KeyStr = s ;
  312.    while (*s>' ' && *s!='=') s++ ;
  313.    if (t = *s)
  314.       *s++ = 0 ;
  315.  
  316.    for(i=0; i<NKEYS; i++)
  317.       if( IsSame(KeyStr, KeyTab[i].Entry) )
  318.          goto found ;
  319.    *tno = -1;
  320.    return (s) ;
  321.  
  322. found: *tno = i ;
  323.    if (KeyTab[i].Type == None)
  324.       return (s) ;
  325.  
  326.    if (t && t <= ' ') {
  327.       for (; *s <= ' ' && *s; s++) ; /* now look for the value part */
  328.       if ((t = *s)=='=')
  329.          s++ ;
  330.    }
  331.    ValStr = "" ;
  332.    if ( t == '=' ) {
  333.       while (*s <= ' ' && *s)
  334.          s++ ;
  335.       if (*s=='\'' || *s=='\"')
  336.          t = *s++ ;               /* get string delimiter */
  337.       else t = ' ' ;
  338.       ValStr = s ;
  339.       while (*s!=t && *s)
  340.          s++ ;
  341.       if (*s)
  342.          *s++ = 0 ;
  343.    }
  344.    switch (KeyTab[i].Type) {
  345.  case Integer:
  346.       if(sscanf(ValStr,"%ld",&ValInt)!=1) {
  347.           sprintf(errbuf,"Non-integer value (%s) given for keyword %s",
  348.               ValStr, KeyStr) ;
  349.           error(errbuf) ;
  350.           ValInt = 0 ;
  351.       }
  352.       break ;
  353.  case Number:
  354.  cas